package cn.itcast.order.service.Impl;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.mapper.SeataFreeTbMapper;
import cn.itcast.order.pojo.SeataFreezeTb;
import cn.itcast.order.service.OrderTCCService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class OrderTCCServiceImpl implements OrderTCCService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SeataFreeTbMapper seataFreeTbMapper;
    
    int flag = 1;


    @Override
    @Transactional
    public void TestTry(int orderId, int freezeNum) {
        //获取全局事务ID——seata自带
        String xid = RootContext.getXID();
        //判断业务悬挂
        SeataFreezeTb oldTb = seataFreeTbMapper.selectByXid(xid);
        if(oldTb != null){
            //如果存在，说明已经执行过空回滚，不需要执行Try
            return;
        }
        //1.扣减可用库存
        orderMapper.updateNumById(orderId,freezeNum);
        //2.记录冻结库存
        seataFreeTbMapper.insert(xid,orderId,freezeNum, SeataFreezeTb.State.TRY);
    }

    @Override
    public boolean TestConfirm(BusinessActionContext context) {
        if(1 == flag){
            flag =2;
            throw new RuntimeException();
        }
        //1.获取事务id，根据id删除冻结库存
        String xId = context.getXid();
        //2.根据事务id删除冻结记录
        int count = seataFreeTbMapper.delete(xId);
        return count == 1;
    }

    @Override
    public boolean TestRollBack(BusinessActionContext context) {
        //1.根据事务id查询冻结记录
        String xId = context.getXid();
        int orderId = (int) context.getActionContext("orderId");
        SeataFreezeTb tb = seataFreeTbMapper.selectByXid(xId);
        //空回滚判断
        if(tb == null){
            //证明Try没执行，需要空回滚,记录空回滚信息
            seataFreeTbMapper.insert(xId,orderId,0, SeataFreezeTb.State.CANCEL);
            return true;
        }
        //幂等性判断
        tb = seataFreeTbMapper.selectByXid(xId);
        if(tb.getState() == SeataFreezeTb.State.CANCEL){
            //已经处理过一次Cancel了，无需重复处理
            return true;
        }
        //1.恢复可用库存
        orderMapper.refund(tb.getOrderId(),tb.getFreezeNum());
        //2.清空冻结库存，修改状态为Cancel
        int count = seataFreeTbMapper.updateById(tb.getId(),0,SeataFreezeTb.State.CANCEL);
        return count == 1;
    }
}
